#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>


typedef struct stnode{
	char symbol[30];
	char dt[10];
	char replace;
	struct stnode *next;
} stnode;
stnode *head;

void parse(char* datatype, char *str)
{	int i, length; //printf("In parse: %s  ",str); 
	 i=0;
	length = strlen(str); 

	while(i < length)
	{	
		char literal[20];
		int len=0;
		while( (*(str+i)!=',') && ( *(str+i)!='\0') )
		{	if((*(str+i)=='_') || isalnum(*(str+i)) )
			{			//{printf("%d\n",i);printf("  %c\n",(*(str+i)));
			literal[len++]= (*(str+i)) ;
						//printf("%d\n",len-1);printf("  %c\n",literal[len-1]);}
			i++;} 		//printf("%d\n",i);
		}
		literal[len]='\0'; 
		
		stnode *node= malloc(sizeof(stnode));
		strcpy(node->symbol,literal);
		strcpy(node->dt, datatype);
		
		if(strcmp(datatype, "int")==0)
			node->replace='i';
		if(strcmp(datatype, "float")==0)
			node->replace='f';
		if(strcmp(datatype, "double")==0)
			node->replace='d';
		if(strcmp(datatype, "char")==0)
			node->replace='c';
			
		node->next=NULL;
		if(head==NULL)
			{ head=node; }
		else
			{ node->next= head;
			  head=node;
			 }
		i++;
	}

}	

char* readTillSemicolon(FILE *fp)
{
	char str[100]; 
	int ch, num;
	num=0;
	ch=fgetc(fp);
	for(ch=fgetc(fp); (ch!=EOF && ch!=';'); ch=fgetc(fp))
	{ str[num++]=ch; }
	str[num]='\0';
	
	//prev warning: function returns address of local var
	char *ret= malloc(strlen(str));
	sprintf(ret,"%s",str);
	return ret;
}

void pass1(char* fileinput)
{
	FILE *fi;
	fi= fopen(fileinput,"r");
	char word[30];
	char *str;
	
	while(!feof(fi))
	{
		if(fscanf(fi,"%s",word)!=1)
			break;
		if(strcmp(word,"int")==0)
		{
			str= readTillSemicolon(fi);
			//printf("In pass1: %s\n",str);
			parse(word,str);
		}
		
		if(strcmp(word,"float")==0)
		{
			str= readTillSemicolon(fi);
			//printf("In pass1: %s\n",str);
			parse(word,str);
		}
		
		if(strcmp(word,"double")==0)
		{
			str= readTillSemicolon(fi);
			//printf("In pass1: %s\n",str);
			parse(word,str);
		}
		
		if(strcmp(word,"char")==0)
		{
			str= readTillSemicolon(fi);
			//printf("In pass1: %s\n",str);
			parse(word,str);
		}
	}
}

char* reverse(char rev[50])
{
	char str[50]; int i,j,len;
	len=strlen(rev); j=0;
	for(i=len-1;i>=0;i--,j++)
	{
		str[j]=rev[i];
	}
	str[j]='\0';
	//printf("%s",str);
	
	char *ret= malloc(strlen(str));
	sprintf(ret,"%s",str);
	return ret;
}

char* getLeft(FILE *fi)
{
	char revStr[50];int revLength=0;
	char letter; char* str;
	
	letter= fgetc(fi); 
	
	while(isalnum(letter))
	{ 
		revStr[revLength]=letter;
		revLength++;
		int fp= ftell(fi);
		fseek(fi,fp-2,SEEK_SET);
		letter=fgetc(fi); //printf("letter: %c ",letter);
	}
	revStr[revLength]='\0';
	//printf("revStr: %s ",revStr);
	
	str=reverse(revStr); 
		
	return str;
}

void extract(FILE *fi,FILE* fo, char substring[50])
{		char* left; char letter;
	int fp= ftell(fi);
					int length= strlen(substring);
					fseek(fi,(fp-length-1),SEEK_SET);
					
					int fp1=ftell(fi);
					letter=fgetc(fi); 
					//printf("1: %c ",letter);
					
					if(letter==' ')
						fseek(fi, fp1-1, SEEK_SET);
					else
						fseek(fi, fp1, SEEK_SET);
					//letter=fgetc(fi); 
					//printf("2: %c ",letter);
					
					left= getLeft(fi);
				
					//fprintf(fo,"%s ",left);
					/*
					if(substring[strlen(substring)-1]!=';')
						strcat(substring,";");
					*/
	stnode *temp= head;
	while(temp!=NULL)
	{
		if(strcmp(temp->symbol,left)==0)
			{fprintf(fo,"%c",temp->replace); //printf("%s ",substring);
			/*
			
			stnode* temp1=head;
			while(temp1!=NULL)
			{if(strcmp(temp->symbol,substring)==0)
				fprintf(fo,"%c",temp->replace);
			else
				fprintf(fo,"%s",substring);
			temp1=temp1->next;
			
			 }
			 */
			fprintf(fo,"%s",substring);
			}
		temp=temp->next;
	}
					fseek(fi,fp,SEEK_SET);
}

void pass2(char *fileinput, char *fileoutput)
{
	FILE *fi, *fo;
	fi= fopen(fileinput,"r");
	fo= fopen(fileoutput,"w");
	char word[30]; 
	stnode *temp= head;
	int flag=0;
	while(!feof(fi))
	{ 
		if(fscanf(fi,"%s",word)!=1)
		break;
		
		//while(temp!=NULL)
		
			char* substring;
			
			substring= strstr(word,"=");
			if(substring!= NULL)
				{ extract(fi,fo, substring);
				  flag=1;
				 }
				 
			substring= strstr(word,"<");
				if(substring!= NULL)
				{ extract(fi,fo, substring);
				  flag=1;
				 }
				
			substring= strstr(word,"+");
				if(substring!= NULL)
				{ extract(fi,fo, substring);
				  flag=2;
				  if(substring[1]=='+')
					{flag=3; 
					if(substring[strlen(substring)-1]!=';')
						fprintf(fo,"%c",';');
					}
				 }
				 
			substring= strstr(word,"-");
				if(substring!= NULL)
				{ extract(fi,fo, substring);
				  flag=2;
				  if(substring[1]=='-')
					{flag=3; 
					if(substring[strlen(substring)-1]!=';')
						fprintf(fo,"%c",';');
					}
				 }
		
	if(flag==2)
	{
		stnode* temp1=head;
		while(temp1!=NULL && flag==2)
		{	substring= strstr(word,temp1->symbol);
			 if(substring!=NULL)
			 { fprintf(fo,"%c;",temp1->replace);
			   flag=0; }
			 temp1=temp1->next;
		 }
	 } 
	 
	 // replacing for functions
	 
	 substring= strstr(word,"(");
	 int a= ftell(fi);
	 
	 if(substring!=NULL)
		{
			int fp= ftell(fi);
			int length= strlen(substring);
			fseek(fi,(fp-length-1),SEEK_SET);
			char *fnName= getLeft(fi);
			//printf("%s: %s\n",substring,fnName);
			
			//if fnName is not common fns, write to fo
			FILE *fkey; char keywd[30]; int kflag=0;
			fkey= fopen("keywords.txt","r");
			while(!feof(fkey))
			{
				fscanf(fkey,"%s",keywd);
				if(strcmp(fnName,keywd)==0)
					kflag=1;
			}
			if(kflag==0)
			{
				//printf("%s, %s",fnName,substring);
					fprintf(fo,"%s",fnName);
			//manipulating substring
			int s, slen, sublen; char sub[40];
			slen=strlen(substring);
			for(s=1, sublen=0;s<slen;s++)
			{
				if((substring[s]!=',') && (substring[s]!=' ') && (substring[s]!=')'))
				{
					sub[sublen]=substring[s];
					sublen++;
				}
				else if((substring[s]==',') || (substring[s]==')'))
				{
					sub[sublen]='\0'; sublen=0;
					//printf("\n%s ",sub);
					stnode* temp= head;
					while(temp!=NULL)
					{
						if(strcmp(sub,temp->symbol)==0)
							fprintf(fo,"%c",temp->replace);
						temp=temp->next;
					}
				}
				
			}
		}
		
		}
	 //replacing fp
	 fseek(fi,a,SEEK_SET);
	}
	fclose(fi);
	fclose(fo);
}

void main(int argc, char* argv[])
{	
	if(argc!=3)
		{printf("Not enough input\n");
		 exit(0);
		}
		
	char fileinput[50], fileoutput[50];

	strcpy(fileinput,argv[1]);
	strcpy(fileoutput,argv[2]);
	
	pass1(fileinput);
	pass2(fileinput, fileoutput);

	FILE *fout=fopen("inputToBloom.txt","a");
	strcat(fileoutput,"\n");
	fwrite(fileoutput,strlen(fileoutput),1,fout);

	fclose(fout);
	/*
	stnode* q =head;
	while(q!=NULL)
	{printf("%s, %s, %c\n",q->symbol,q->dt,q->replace);
	 q=q->next;
	 }
	printf("Finished\n");
	*/
}
